package com.example.demo.bizhan.thread;

/**
 * @description: xxx
 * @time: 2020-10-27 20:56
 * @author: baojinlong
 * 主线程获取子线程中的返回值
 * 1) 主线程等待
 * 2) 使用线程join方法来获取子线程返回值
 * 3) 使用Callable接口:FutureTask
 * 4) 使用线程池方式
 * 问题演示:多线程在操作共享数据或者是操作数据的线程代码有多行,如果有其它线程也参与了运算,就会导致安全问题.
 * 解决方案:synchronized枷锁,同一个时间点只有一个线程执行方法
 **/
public class ThreadDemo06 {
    public static void main(String[] args) {
        Bank bank = new Bank();
        MoneyThread moneyThread = new MoneyThread(bank);
        Thread thread1 = new Thread(moneyThread);
        Thread thread2 = new Thread(moneyThread);
        thread1.start();
        thread2.start();
    }

}

class Bank {
    private int money = 1000;

    public int getMoneyFromBank2(int number) {
        if (number < 0) {
            System.out.println("不能取负数的钱...");
            return -1;
        } else if (number > money) {
            System.out.println("余额不足1 ...");
            return -1;
        } else if (money < 0) {
            System.out.println("余额不足2 ...");
            return -2;
        } else {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("取钱过程中出现异常" + e);
            }
            money -= number;
            System.out.println("还剩money " + money);
            return number;
        }
    }

    public synchronized int getMoneyFromBank(int number) {
        if (number < 0) {
            System.out.println("不能取负数的钱...");
            return -1;
        } else if (number > money) {
            System.out.println("余额不足1...");
            return -1;
        } else if (money < 0) {
            System.out.println("余额不足2...");
            return -2;
        } else {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("取钱过程中出现异常" + e);
            }
            money -= number;
            System.out.println("还剩money " + money);
            return number;
        }
    }
}

class MoneyThread implements Runnable {
    private Bank bank;

    public MoneyThread(Bank bank) {
        this.bank = bank;
    }

    @Override
    public void run() {
        bank.getMoneyFromBank(800);
    }
}